<?php
/**
 * Abstract.php
 *
 * Momoger_Model 抽象对象
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://momoger.com/license
 *
 * @category	Momoger
 * @package 	Momoger_Model
 * @author 		Leo
 * @version    	1.0
 * @copyright  	Copyright © 2009 www.momoger.com All Rights Reserved.
 * @license    	http://momoger.com/license     New BSD License
 */

/**
 * Momoger_Model 抽象类
 *
 * @category 	Momoger
 * @package		Momoger_Model
 * @copyright  	Copyright © 2009 www.momoger.com All Rights Reserved.
 * @license    	http://momoger.com/license     New BSD License
 */
abstract class Momoger_Model_Abstract {

	/**
	 * 数据映射对象。
	 *
	 * @var Momoger_Model_Mapper_Abstract
	 */
	protected $_mapper = null;

	/**
	 * 模型属性
	 *
	 * @var array
	 */
	protected $_attributes = array();

	/**
	 * 构造函数.
	 *
	 * @param mixed $attribute 属性名
	 * @param mixed $value 字段值
	 */
	public function __construct($attribute = null, $value = null) {
		$this->set($attribute, $value);
	}

    /**
     * 获取数据映射对象
     *
     * @return Momoger_Model_Mapper_Abstract
     */
    abstract protected function getMapper();

	/**
	 * 设置模型属性
	 *
	 * @param mixed $attribute 属性名
	 * @param mixed $value 属性值
	 * @return Momoger_Model_Abstract
	 */
	public function set($attribute = null, $value = null) {
		if ($attribute instanceof stdClass ) {
			$this->set(get_object_vars($attribute));
		} else if (is_array($attribute) && count($attribute)) {
			foreach ($attribute as $k => $v) {
				$this->_attributes[$k] = $v;
			}
		} else {
			if (!empty($attribute)) {
				$this->_attributes[$attribute] = $value;
			}
		}
		return $this;
	}

	/**
	 * 获取对象属性值.
	 *
	 * @param string $attribute 属性名
	 * @param mixed $default 默认值
	 * @return mixed
	 */
	public function get($attribute, $default = null) {
		if (array_key_exists($attribute, $this->_attributes)) {
			return $this->_attributes[$attribute];
		}
		return $default;
	}

	/**
	 * 获取对象所有属性
	 *
	 * @return array
	 */
	public function getAll() {
		return $this->_attributes;
	}

	/**
	 * 重置对象
	 *
	 * @param mixed $attribute 对象属性
	 * @param mixed $value 属性值
	 * @return Momoger_Model_Abstract
	 */
	public function reset($attribute = null, $value = null) {
		$this->_attributes = array();
		$this->set($attribute, $value);
		return $this;
	}

	/**
	 * 清除对象属性
	 *
	 * @param string|array $attribute 要清除的属性名
	 * @return Momoger_Model_Abstract
	 */
	public function remove($attribute = null) {
		if (is_array($attribute) && count($attribute)) {
			foreach ($attribute as $v) {
				if (array_key_exists($v, $this->_attributes)) {
					unset($this->_attributes[$v]);
				}
			}
		} else {
			if (!empty($attribute)) {
				if (array_key_exists($attribute, $this->_attributes)) {
					unset($this->_attributes[$attribute]);
				}
			}
		}
		return $this;
	}

    /**
     * 保存数据映射对象
     *
     * @return Momoger_Model_Abstract
     */
    public function save() {
		return $this->getMapper()->save($this);
    }

    /**
     * 保存新数据到 DAO
     *
     * @return Momoger_Model_Abstract
     */
    public function insert() {
    	return $this->getMapper()->insert($this);
    }

    /**
     * 更新数据到DAO
     *
     * @param string|array $where 批量更新条件
     * @return Momoger_Model_Abstract
     */
    public function update($where = null) {
    	return $this->getMapper()->update($this, $where);
    }

    /**
     * 删除模型在DAO中的数据
     *
     * @param string|array $where 批量删除条件
     * @return Momoger_Model_Abstract
     */
    public function delete($where = null) {
    	return $this->getMapper()->delete($this, $where);
    }

	/**
	 * 魔术方法 __set()
	 *
	 * @param string $name 属性名
	 * @param mixed $value 属性值
	 * @return Momoger_Model_Abstract
	 */
	public function __set($name, $value) {
		$this->set($name, $value);
		return $this;
	}

	/**
	 * 魔术方法 __get()
	 *
	 * @param string $name 属性名
	 * @return mixed
	 */
	public function __get($name) {
		return $this->get($name, null);
	}

    /**
     * 更加模型身份ID获取模新保存在数据源中的数据, 成功找到更新模型本身数据.
     *
     * @param int|string $key 模型身份ID
     * @return Momoger_Model_Abstract
     */
    public function find($key) {
    	return $this->getMapper()->find($this, $key);
    }

    /**
     * 根据条件查找模型保存在数据源中的数据, 成功找到更新模型本身数据.
     *
     * @param string|array $where 过滤条件
     * @param string|array $order 排序条件
     * @return Momoger_Model_Abstract
     */
    public function findRow($where = null, $orlder = null) {
    	return $this->getMapper()->findRow($this, $where, $orlder);
    }

    /**
     * 根据条件查找模型保存在数据源中的批量数据, 成功找到返回模型数组.
     *
     * @param string|array $where 过滤条件
     * @param string|array $order 排序条件
     * @param int $limit 结果限制
     * @param int $offset 开始位置
     * @return array
     */
    public function findAll($where = null, $order = null, $limit = 500, $offset = 0) {
    	return $this->getMapper()->findAll($this, $where, $order, $limit, $offset);
    }

	/**
	 * 获取系统信息记录对象
	 *
	 * @return App_System_Logger
	 */
	protected function logger() {
		return App_System_Logger::getInstance();
	}

	/**
	 * 获取系统缓存对象
	 *
	 * @return App_System_Cache
	 */
	protected function cache() {
		return App_System_Cache::getInstance();
	}

	/**
	 * 设置模型数据映射对象
	 *
	 * @param Momoger_Model_Mapper_Abstract $mapper
	 * @return Momoger_Model_Abstract
	 */
	protected function setMapper(Momoger_Model_Mapper_Abstract $mapper) {
        $this->_mapper = $mapper;
        return $this;
    }
}